@(commitId: String,
  fileName: Option[String] = None,
  oldLineNumber: Option[Int] = None,
  newLineNumber: Option[Int] = None,
  issueId: Option[Int] = None,
  hasWritePermission: Boolean,
  repository: gitbucket.core.service.RepositoryService.RepositoryInfo,
  focus: Boolean = false,
  uid: Long = new java.util.Date().getTime())(implicit context: gitbucket.core.controller.Context)
@import gitbucket.core.view.helpers
@if(context.loginAccount.isDefined){
  @if(!fileName.isDefined){<hr/><br/>}
  <form method="POST" validate="true">
    <div class="panel panel-default issue-comment-box">
      <div class="panel-body">
        @gitbucket.core.helper.html.preview(
          repository         = repository,
          content            = "",
          enableWikiLink     = false,
          enableRefsLink     = true,
          enableLineBreaks   = true,
          enableTaskList     = true,
          hasWritePermission = hasWritePermission,
          completionContext  = "issues",
          style              = "height: 100px; max-height: 150px;",
          elastic            = true,
          focus              = focus,
          uid                = uid
        )
        @if(fileName.isDefined){
          <div class="pull-right">
            <input type="button" class="btn btn-default" value="Cancel"/>
            <input type="submit" id="btn-inline-comment-@uid" class="btn btn-success" formaction="@helpers.url(repository)/commit/@commitId/comment/new" value="Comment"/>
          </div>
        }
      </div>
    </div>
    @if(!fileName.isDefined){
      <div class="pull-right">
        <input type="submit" class="btn btn-success" formaction="@helpers.url(repository)/commit/@commitId/comment/new" value="Comment on this commit"/>
      </div>
    }
    @issueId.map { issueId => <input type="hidden" name="issueId" value="@issueId"> }
    @fileName.map { fileName => <input type="hidden" name="fileName" value="@fileName"> }
    @oldLineNumber.map { oldLineNumber => <input type="hidden" name="oldLineNumber" value="@oldLineNumber"> }
    @newLineNumber.map { newLineNumber => <input type="hidden" name="newLineNumber" value="@newLineNumber"> }
  </form>
  <script>
    $('#btn-inline-comment-@uid').click(function(e) {
      e.preventDefault();
      var $form = $(e.target).attr('disabled', 'disabled').closest('form');
      var param = {};
      $($form.serializeArray()).each(function(i, v) {
        param[v.name] = v.value;
      });

      @if(newLineNumber.isDefined){
        var diff = getDiffData($('table[filename="@fileName"] table.diff tr:has(th.line-num.newline[line-number="@newLineNumber"])'));
        param['diff'] = JSON.stringify(diff);
      } else if(oldLineNumber.isDefined){
        var diff = getDiffData($('table[filename="@fileName"] table.diff tr:has(th.line-num.oldline[line-number="@oldLineNumber"])'));
        param['diff'] = JSON.stringify(diff);
      }

      $.ajax({
        url: '@helpers.url(repository)/commit/@commitId/comment/_data/new',
        type: 'POST',
        data: param
      }).done(function(data) {
        var tmp;
        if (window.viewType == 0) {
          tmp = '@(oldLineNumber, newLineNumber) match {
            case (Some(_), None) => {<td colspan="2" class="comment-box-container"></td><td colspan="2"></td>}
            case (None, Some(_)) => {<td colspan="2"></td><td colspan="2" class="comment-box-container"></td>}
            case _ => {<td colspan="3" class="comment-box-container"></td>}
          }'
        } else {
          tmp = '<td colspan="3" class="comment-box-container"></td>'
        }
        var $tr = $form.closest('tr.not-diff');

        // Apply comment
        var $addedCommentContent = $tr.removeClass('inline-comment-form').html(tmp).find('.comment-box-container');
        $addedCommentContent.html(data);
        $addedCommentContent.find('div[class*=commit-commentContent-]').on('click', ':checkbox', function(ev){
          var $commentContent = $(ev.target).parents('div[class*=commit-commentContent-]'),
            commentId = $commentContent.attr('class').match(/commit-commentContent-.+/)[0].replace(/commit-commentContent-/, ''),
            checkboxes = $commentContent.find(':checkbox');
          $.get('@helpers.url(repository)/commit_comments/_data/' + commentId, { dataType : 'html' },
            function(responseContent){
              $.ajax({
                url: '@helpers.url(repository)/commit_comments/edit/' + commentId,
                type: 'POST',
                data: {
                  issueId : 0,
                  content : applyTaskListCheckedStatus(responseContent, checkboxes)
                },
                success: function(data) {
                  $('.commit-commentContent-' + commentId).html(data.content);
                }
              });
            }
          );
        });

        // Show reply comment form
        var replyComment = $tr.prev().find('.reply-comment').closest('.not-diff').show();
        if(replyComment.length != 0){
          replyComment.remove();
          $tr.after(replyComment);
        } else {
          var $v = $('<div class="commit-comment-box reply-comment-box">')
            .append($('<input type="text" class="form-control reply-comment" placeholder="Reply...">')
              .attr('data-filename', '@fileName')
              .attr('data-newline',  @newLineNumber.getOrElse("undefined"))
              .attr('data-oldline',  @oldLineNumber.getOrElse("undefined")));

          @if(oldLineNumber.isDefined){
            @if(newLineNumber.isDefined){
              var tmp = getInlineContainer();
            } else {
              var tmp = getInlineContainer('old');
            }
            tmp.children('td:first').html($v);
          } else {
            var tmp = getInlineContainer('new');
            tmp.children('td:last').html($v);
          }
          $tr.after(tmp);
        }

        // $('#comment-list').append(data);
        // if (typeof $('#show-notes')[0] !== 'undefined' && !$('#show-notes')[0].checked) {
        //   $('#comment-list').children('.inline-comment').hide();
        // }
      }).fail(function(req) {
        $(e.target).removeAttr('disabled');
        $('#error-content', $form).html($.parseJSON(req.responseText).content);
      });
    });

    function getInlineContainer() {
      if (window.viewType == 0) {
        if(@newLineNumber.isDefined){
          return $('<tr class="not-diff"><td colspan="2"></td><td colspan="2" class="comment-box-container"></td></tr>');
        }
        if(@oldLineNumber.isDefined){
          return $('<tr class="not-diff"><td colspan="2" class="comment-box-container"></td><td colspan="2"></td></tr>');
        }
      }
      return $('<tr class="not-diff"><td colspan="3" class="comment-box-container"></td></tr>');
    }

    function getDiffData(tr){
      if(window.viewType === 0) {
        return getDiffDataOnSplitMode(tr);
      } else {
        return getDiffDataOnUnifiedMode(tr);
      }
    }

    function getDiffDataOnUnifiedMode(tr) {
      var result = [];
      var count = 0;

      while(tr && count < 4){
        var oldTh = tr.find('th.oldline');
        var newTh = tr.find('th.newline');

        var oldLineNumber = oldTh.attr('line-number');
        var newLineNumber = newTh.attr('line-number');

        if(!oldLineNumber && !newLineNumber){
          break;
        }

        result.unshift({
          'oldLine': oldLineNumber,
          'newLine': newLineNumber,
          'type': tr.has('td.insert').length > 0 ? 'insert' : tr.has('td.delete').length > 0 ? 'delete' : 'equal',
          'text': tr.find('td span').text()
        });

        tr = tr.prev('tr:has(th.line-num)');
        count++;
      }

      return result;
    }

    function getDiffDataOnSplitMode(tr) {
      var result = [];
      var count = 0;

      while(tr && count < 4){
        var oldTh = tr.find('th.oldline');
        var newTh = tr.find('th.newline');

        var oldLineNumber = oldTh.attr('line-number');
        var newLineNumber = newTh.attr('line-number');

        if(!oldLineNumber && !newLineNumber){
          break;
        }

        var oldTd = oldTh.next();
        var newTd = newTh.next();

        if (oldTd.hasClass('equal') && newTd.hasClass('equal')) {
          result.unshift({
            'oldLine': oldLineNumber,
            'newLine': newLineNumber,
            'type': 'equal',
            'text': newTd.find('span').text()
          });
          count++;
        } else {
          if(newLineNumber) {
            result.unshift({
              'newLine': newLineNumber,
              'type': 'insert',
              'text': newTd.find('span').text()
            });
            count++;
          }
          if(oldLineNumber) {
            result.unshift({
              'oldLine': oldLineNumber,
              'type': 'delete',
              'text': oldTd.find('span').text()
            });
            count++;
          }
        }
        tr = tr.prev('tr:has(th.line-num)');
      }

      return result;
    }
  </script>
}
